package site.shader85.Kingdoms.domain;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.bukkit.Location;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.configuration.serialization.SerializableAs;
import org.bukkit.entity.Entity;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

import site.shader85.Kingdoms.KingdomsPlugin;
import site.shader85.Kingdoms.domain.area.Area;
import site.shader85.Kingdoms.domain.area.Position;

@SerializableAs("Domain")
public class Domain implements ConfigurationSerializable {

	private String name;
	private String world;
	private Area area;
	private String owner;
	private ArrayList<String> admins = Lists.newArrayList();
	private ArrayList<Manor> manors = Lists.newArrayList();
	private Position core;
	private static Map<String, Domain> domains = Maps.newHashMap();

	private Domain(String name, String world, Area area, Position core) {
		this.name = name;
		this.world = world;
		this.area = area;
		this.core = core;
	}
	
	public static int getSize(){
		return domains.size();
	}
	
	public String getName() {
		return name;
	}

	public static Collection<Domain> getDomains() {
		return domains.values();
	}

	public String getWorldName() {
		return world;
	}

	public String getOwner() {
		return owner;
	}

	public void addAdmin(String admin) {
		admins.add(admin);
	}

	public void removeAdmin(String admin) {
		admins.remove(admin);
	}
	
	public boolean isAdmin(String admin){
		return admins.contains(admin);
	}
	
	public void setOwner(String owner) {
		this.owner = owner;
	}

	public Position getCore() {
		return core;
	}

		
	public int getHeight(){
		return this.area.getHeight();
	}
	
	public int getXZ(){
		return this.area.getXZ();
	}
	
	public boolean inDomain(Entity e) {
		return inDomain(e.getLocation());
	}

	public boolean inDomain(Location loc) {
		return area.inArea(loc);
	}

	public boolean inDomain(Area a) {
		return area.inArea(a);
	}

	@SuppressWarnings("unchecked")
	public List<Manor> getManors() {
		return (List<Manor>) manors.clone();
	}

	public boolean createManor(Area a, String name) {
		if (inDomain(a))
			if (!hasManor(name))
				return manors.add(Manor.createManor(name, this, a));
		return false;
	}

	public static Domain createDomain(String name, String world, Area area, Position core) {
		return createDomain(name,world,area,core,false);
	}
	
	public static Domain createDomain(String name, String world, Area area, Position core,boolean deSerialize) {
		Domain d = new Domain(name, world, area, core);
		domains.put(name, d);
		if(!deSerialize)
			KingdomsPlugin.getInstance().getDomainConfig().setDomain(d);
		return d;
	}

	public static void remove(Domain d) {
		domains.remove(d.getName());
	}

	public static Domain getDomain(String name) {
		return domains.get(name);
	}

	public boolean hasManor(String name) {
		for (Manor m : manors) {
			if (m.getName().equals(name))
				return true;
		}
		return false;
	}

	@Override
	public Map<String, Object> serialize() {
		HashMap<String, Object> table = Maps.newHashMap();
		table.put("area", area);
		table.put("manors", manors);
		table.put("name", name);
		table.put("world", world);
		table.put("core", core);
		table.put("owner", owner);
		table.put("admins", admins);
		return table;
	}

	// String name, String world, Area area,Position core
	@SuppressWarnings("unchecked")
	public static Domain deserialize(Map<String, Object> table) {
		String name = (String) table.get("name");
		String world = (String) table.get("world");
		Area area = (Area) table.get("area");
		Position core = (Position) table.get("core");
		String owner = (String) table.get("owner");
		List<Manor> manors = (List<Manor>) table.get("manors");
		List<String> admins = (List<String>) table.get("admins");
		Domain instance = Domain.createDomain(name, world, area, core,true);
		for (Manor m : manors) {
			instance.manors.add(m);
		}
		for (String s : admins) {
			instance.admins.add(s);
		}
		instance.owner = owner;
		return instance;
	}
}
